package ctf

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"net/http"
	"pdocker/config"
	"pdocker/docker"
	"strconv"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
)

func (t *Task) Create() error {
	resp, err := docker.CreateContainer(t.Image, t.Name, t.Flags, t.Ports)
	if err != nil {
		return err
	}
	t.Id = resp
	return nil
}

func (t *Task) Start() {
	_ = docker.StartContainer(t.Id)
	container, err := docker.GetContainerById(t.Id)
	if err != nil {
		log.Errorln(err)
		//var table TaskTable = TaskTable{Data: *t}
		//table.Delete()
	}
	if len(t.Ports) > 0 {
		p, _ := strconv.Atoi(strings.Split(t.Ports[0], "/")[0])
		port, _ := docker.GetPublicPort(uint16(p), container)
		url := fmt.Sprintf("%s?taskid=%s&url=%s&uid=%s",
			t.Task.CallBack, t.Task.TaskId, fmt.Sprintf("%s:%d", config.Config.Docker.Host, port), t.Task.UID)
		log.Debugln("开始回调 url: ", url)
		_, _ = http.Get(url)
	}
	t.Init()
	//todo 优化回调信息
}

func (t *Task) Delete() {
	if t.Id != "" {
		_ = docker.DeleteContainer(t.Id, false)
	} else {
		log.Warningf("任务id: %s 容器id为空（数据错误，记录已删除）\n", t.Task.TaskId)
	}

}

func (t *Task) Update(timeStamp int64) {
	log.Debugf("update task: %s timer %d", t.Task.TaskId, timeStamp)
	ok, timer := t.Timer(timeStamp)
	if ok {
		log.Debugf("更新任务: %s 成功", t.Task.TaskId)
		timerList[t.Task.TaskId] = timer
	} else {
		log.Debugf("更新任务: %s 失败 时间已经过期，尝试删除", t.Task.TaskId)
		t.Delete()
		table := TaskTable{TaskId: t.Task.TaskId, Data: *t}
		table.Delete()
	}
}

func (t *Task) Init() {
	log.Debugf("update task: %s timer %d", t.Task.TaskId, t.Task.DestroyTimeStamp)
	ok, timer := t.Timer(t.Task.DestroyTimeStamp)
	if ok {
		log.Debugf("初始化任务: %s 成功", t.Task.TaskId)
		timerList[t.Task.TaskId] = timer
	} else {
		log.Warningf("初始化任务: %s 失败 时间已经过期，尝试删除", t.Task.TaskId)
		t.Delete()
		table := TaskTable{TaskId: t.Task.TaskId, Data: *t}
		table.Delete()

	}
}

func (t *Task) Timer(timestamp int64) (bool, *time.Timer) {
	duration := time.Until(time.Unix(timestamp, 0))
	if duration < 0 {
		return false, nil
	}
	log.Debugf("预定销毁时间 %v \n", duration)
	return true, time.AfterFunc(duration, func() {
		t.Delete()
	})
}

func (t *Task) Scan(val interface{}) (err error) {
	if bb, ok := val.([]byte); ok {
		err := json.Unmarshal(bb, &t)
		return err
	}
	return nil
}

func (t *Task) Value() (driver.Value, error) {
	response, _ := json.Marshal(t)
	return response, nil
}

func (t *Task) Copy() *Task {
	jsonData, _ := json.Marshal(t)
	copyTask := new(Task)
	_ = json.Unmarshal(jsonData, copyTask)
	return copyTask
}

func (t *Task) String() string {
	response, _ := json.Marshal(t)
	return string(response)
}
